home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_315 / surf / poly.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  9KB  |  392 lines

  1. #include <math.h>
  2. #include "mytypes.h"
  3. #include "scrnio.h"
  4. #include "bezpt.h"
  5. #include "revolve.h"
  6. #include "control.h"
  7. #include "poly.h"
  8. #include "readilbm.h"
  9. #include "menuexp.h"
  10.  
  11. bool  SpecOn = false; /* specular lighting enable - default off */
  12.  
  13. float Ambience = DefAmbience;
  14. float PtIntensity = (float)DefIntensity;
  15. float Kd = DefKd,
  16.       Ks = DefKs;
  17.  
  18. Pt3 LightSrc = {
  19.         DefLightSrcX,
  20.         DefLightSrcY,
  21.         DefLightSrcZ
  22.         };
  23.  
  24. static
  25. Rhomboid *polylist = null,
  26.          *nextpoly;
  27.  
  28. MapRhomboid *mpolylist = null,
  29.         *mnextpoly;
  30.  
  31. static
  32. int polyspace = 0;
  33.  
  34.  
  35. static bool shadeflag;
  36.  
  37. long CalcMaxPolyNum() {
  38.     return( GetNumSegs() * BezMesh * RevMesh );
  39. }
  40.  
  41. static
  42. bool PrepPoly()
  43. {
  44.         if( polylist ) free( (char *)polylist );
  45.         polylist = (Rhomboid *)malloc( CalcMaxPolyNum() * sizeof(Rhomboid));
  46.         if( !polylist ) {
  47.             OutErr("PrepPoly: not enough memory");
  48.             return( true );
  49.         }
  50.         nextpoly = polylist;
  51.         return(false); /* success = 0 */
  52. }
  53.  
  54.  
  55. static bool
  56. PrepMPoly()
  57. {
  58.         if( mpolylist ) free( (char *)mpolylist );
  59.         mpolylist = (MapRhomboid *)
  60.                     malloc( CalcMaxPolyNum() * sizeof(MapRhomboid));
  61.         if( !mpolylist ) {
  62.             OutErr("PrepPoly: not enough memory");
  63.             return( true );
  64.         }
  65.         mnextpoly = mpolylist;
  66.         return(false); /* success = 0 */
  67. }
  68.  
  69.  
  70. /*
  71.  * Multiply a vector by scalar quantity
  72.  */
  73. void ScaleVec( fact, src, dst )
  74.         float fact;
  75.         Pt3 *src, *dst;
  76. {
  77.         dst->x = src->x * fact;
  78.         dst->y = src->y * fact;
  79.         dst->z = src->z * fact;
  80. }
  81. /*
  82.  * convert a vector to a unitized vector
  83.  * if possible
  84.  */
  85. void Unitize( vec )
  86.         Pt3 *vec;
  87. {
  88.         float len;
  89.  
  90.         len = vec->x*vec->x + vec->y*vec->y + vec->z*vec->z;
  91.         len = sqrt( len );
  92.         if( len != 0.0 ) {
  93.                 vec->x /= len;
  94.                 vec->y /= len;
  95.                 vec->z /= len;
  96.         }
  97. }
  98.  
  99. /*
  100.  * calculate a vector from two points
  101.  */
  102. void CalcVector( src1, src2, dest )
  103. Pt3 *src1, *src2, *dest ;
  104. {
  105.         dest->x = src1->x - src2->x;
  106.         dest->y = src1->y - src2->y;
  107.         dest->z = src1->z - src2->z;
  108. }
  109.  
  110.  
  111.  
  112.  
  113. /*
  114.  * calculate a normal from a list of polygons. This routine does the
  115.  * logical trick of trying to exclude each point in turn if the
  116.  * normal can not be calculated, or something of the sort.
  117.  * a value of true is returned if a normal with a nonzero z component
  118.  * could not be calculated
  119.  */
  120.  
  121. bool CalcNormal( vxlist, normal)
  122.         PtGen *vxlist[];
  123.         register Pt3 *normal;
  124. {
  125.         int i, k, m;
  126.         Pt3 *j[3];
  127.         Pt3 v1, v2;
  128.  
  129.         for( i = 0; i < RhomVxNum; i++ ) {
  130.                 for( k = 0, m = 3; m--; k++ ) {
  131.                         if( k == i ) {
  132.                                 k++;
  133.                         }
  134.                         j[m] = &vxlist[k]->d3;
  135.                 }
  136.                 CalcVector( j[1], j[0], &v1 );
  137.                 CalcVector( j[2], j[1], &v2 );
  138.  
  139.                 normal->z = v1.x*v2.y - v1.y*v2.x;
  140.                 if( normal->z == 0 ) {
  141.                         continue;
  142.                 }
  143.                 normal->x = v1.y*v2.z - v1.z*v2.y;
  144.                 normal->y = v1.z*v2.x - v1.x*v2.z;
  145.                 if( normal->z < 0 ) {
  146.                         normal->x = -normal->x;
  147.                         normal->y = -normal->y;
  148.                         normal->z = -normal->z;
  149.                 }
  150.                 Unitize(normal);
  151.                 return( false );
  152.         }
  153.         return(true);
  154. }
  155.  
  156.  
  157. /*
  158.  * Euclidean dot product.
  159.  * I wonder what the minkowski dot product would look like
  160.  */
  161. float DotProd( v1, v2 )
  162.         Pt3 *v1, *v2;
  163. {
  164.         return( v1->x*v2->x + v1->y*v2->y + v1->z*v2->z );
  165. }
  166.  
  167.  
  168.  
  169.  
  170.  
  171. /*
  172.  * define a polygon as a set of four points
  173.  * returns true if polygon created
  174.  */
  175. static bool CreatePoly(curpoly, p0, p1, p2, p3)
  176.     register Rhomboid *curpoly;
  177.     PtGen *p0, *p1, *p2, *p3;
  178. {
  179.  
  180.     Pt3 normal;
  181.     PtGen *list[RhomVxNum];
  182.  
  183.     list[0] = p0; list[1] = p1; list[2] = p2; list[3] = p3;
  184.     /*
  185.      * compute stuff needed only if producing shaded image
  186.      */
  187.     if( shadeflag ) {
  188.             Pt3 lvec;
  189.             Pt3 center;
  190.             float ptintens;
  191.             float ldotn; /* light vector dot normal */
  192.             /*
  193.             * if cant compute normal, then junk polygon
  194.             */
  195.             if( CalcNormal( list, &normal )) {
  196.                 return(false);
  197.             }
  198.  
  199.             curpoly->intensity = Ambience;
  200.             center.x = ( list[0]->d3.x
  201.                     + list[1]->d3.x
  202.                     + list[2]->d3.x
  203.                     + list[3]->d3.x)/4.0;
  204.             center.y = ( list[0]->d3.y
  205.                     + list[1]->d3.y
  206.                     + list[2]->d3.y
  207.                     + list[3]->d3.y)/4.0;
  208.             center.z = ( list[0]->d3.z
  209.                     + list[1]->d3.z
  210.                     + list[2]->d3.z
  211.                     + list[3]->d3.z)/4.0;
  212.  
  213.             curpoly->depth = center.z;
  214.  
  215.             CalcVector( ¢er, &LightSrc, &lvec );
  216.             Unitize( &lvec );
  217.             ldotn = DotProd( &lvec, &normal );
  218.             if( ldotn < 0 ) {
  219.                 ptintens = PtIntensity * Kd * -ldotn;
  220.                 curpoly->intensity += ptintens;
  221.             }
  222.             /*
  223.              * calculate specular component
  224.              */
  225.             if( SpecOn && ldotn < 0 ) {
  226.                 float Kspec, Is;
  227.                 Pt3 rvec; /* lvec reflected through poly */
  228.  
  229.                 ScaleVec( 2*ldotn, &normal, &rvec );
  230.                 CalcVector(&lvec, &rvec, &rvec );
  231.                 Unitize( ¢er );
  232.                 Kspec = DotProd( &rvec, ¢er);
  233.  
  234.                 if( Kspec <= 0.0 ) {
  235.                     Is = Ks * Kspec * Kspec* PtIntensity;
  236.                     curpoly->intensity += Is;
  237.                 }
  238.             }
  239.  
  240.             if( curpoly->intensity > 1.0 ) {
  241.                 curpoly->intensity = 1.0;
  242.             }
  243.     }
  244.     else {
  245.         /*
  246.          * calculate depth of polygon
  247.          * for now, try an average of the vertex depths
  248.          */
  249.         curpoly->depth =( list[0]->d3.z
  250.                 + list[1]->d3.z
  251.                 + list[2]->d3.z
  252.                 + list[3]->d3.z)/4.0;
  253.     }
  254.     /*
  255.      * store index to screen coordinates
  256.      */
  257.     curpoly->pt[0] = p0->d2;
  258.     curpoly->pt[1] = p1->d2;
  259.     curpoly->pt[2] = p2->d2;
  260.     curpoly->pt[3] = p3->d2;
  261.  
  262.     return(true);
  263. }
  264. /*
  265.  * passable procedure for creating polygons without mapping
  266.  */
  267. static
  268. void AcceptPoly(p0, p1, p2, p3)
  269.     PtGen *p0, *p1, *p2, *p3;
  270. {
  271.     if( CreatePoly(nextpoly, p0, p1, p2,p3)) {
  272.         nextpoly++;
  273.     }
  274. }
  275.  
  276. static
  277. void AcceptMPoly( p0, p1, p2, p3)
  278.     PtGen *p0, *p1, *p2, *p3;
  279. {
  280.     if( CreatePoly(&mnextpoly->rhom, p0, p1, p2,p3)) {
  281.         mnextpoly->bezindex = RevImageB;
  282.         mnextpoly->revindex = RevImageR;
  283.         mnextpoly++;
  284.     }
  285. }
  286.  
  287.  
  288.  
  289.  
  290.  
  291. /*
  292.  * compare the depth of two polygons for SortPoly
  293.  */
  294. static int CmpDepth( a, b )
  295.         Rhomboid *a, *b;
  296. {
  297.         if( a->depth < b->depth ) return(-1);
  298.         else if( a->depth > b->depth ) return(1);
  299.         else return(0);
  300. }
  301.  
  302. static int CmpMDepth( a, b )
  303.         MapRhomboid *a, *b;
  304. {
  305.         if( a->rhom.depth < b->rhom.depth ) return(-1);
  306.         else if( a->rhom.depth > b->rhom.depth ) return(1);
  307.         else return(0);
  308. }
  309.  
  310.  
  311.  
  312.  
  313.  
  314. void RevNoShade() {
  315.         Rhomboid *i;
  316.         if( GetNumSegs() < 1 ) {
  317.                 return;
  318.         }
  319.  
  320.         ClrAbort();
  321.         shadeflag = false;
  322.         if( PrepPoly() ) return;
  323.         if( Revolve(AcceptPoly) ) return;
  324.         CurMode = NOTACTIVE;
  325.  
  326.         qsort( (char *)polylist, nextpoly - polylist,
  327.                 sizeof(Rhomboid), CmpDepth);
  328.  
  329.         ClrWindow(false);
  330.  
  331.         for( i = polylist; i< nextpoly; i++ ) {
  332.             if( AbortDraw ) return;
  333.                 DrawRhomFrame( i->pt );
  334.         }
  335. }
  336.  
  337.  
  338.  
  339.  
  340. void RevShade() {
  341.         register Rhomboid *i;
  342.  
  343.         if( !AllocDither()) return; /* not enough memory */
  344.         if( GetNumSegs() < 1 ) {
  345.                 return;
  346.         }
  347.         CurMode = NOTACTIVE;
  348.         ClrAbort();
  349.         shadeflag = true;
  350.         if( PrepPoly() || Revolve(AcceptPoly) ) {
  351.             return;
  352.         }
  353.         qsort( (char *)polylist, nextpoly-polylist,
  354.                 sizeof(Rhomboid), CmpDepth);
  355.  
  356.         ClrWindow(false);
  357.  
  358.         for( i = polylist; i< nextpoly; i++ ) {
  359.                 if( AbortDraw ) return;
  360.                 DrawRhomShade( i );
  361.         }
  362. }
  363.  
  364.  
  365.  
  366. void RevMap() {
  367.     register MapRhomboid *i;
  368.  
  369.     ClrAbort();
  370.     if( GetNumSegs() < 1 ) {
  371.             return;
  372.     }
  373.     if( InitMapping() ) {
  374.         return;
  375.     }
  376.     CurMode = NOTACTIVE;
  377.     shadeflag = true;
  378.  
  379.  
  380.     if( PrepMPoly() || Revolve(AcceptMPoly) ) {
  381.         return;
  382.     }
  383.     qsort( (char *)mpolylist, mnextpoly-mpolylist,
  384.         sizeof(MapRhomboid), CmpMDepth);
  385.     ClrWindow(false);
  386.  
  387.     for( i = mpolylist; i< mnextpoly; i++ ) {
  388.             if( AbortDraw ) return;
  389.             DrawRhomMap(i);
  390.     }
  391. }
  392.